package com.an.trip.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.an.common.core.domain.PageQuery;
import com.an.common.core.page.TableDataInfo;
import com.an.common.exception.blog.BlogException;
import com.an.common.exception.trip.TripException;
import com.an.common.utils.BeanCopyUtils;
import com.an.common.utils.StringUtils;
import com.an.trip.domain.TripDailyRecord;
import com.an.trip.domain.TripMember;
import com.an.trip.domain.bo.TripMemberBo;
import com.an.trip.domain.vo.TripMemberVo;
import com.an.trip.mapper.TripDailyRecordMapper;
import com.an.trip.mapper.TripMemberMapper;
import com.an.trip.service.ITripMemberService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 行程人员Service业务层处理
 *
 * @author Ann
 * @date 2024-12-04
 */
@RequiredArgsConstructor
@Service
public class TripMemberServiceImpl implements ITripMemberService {

    private final TripMemberMapper baseMapper;

    private final TripDailyRecordMapper tripDailyRecordMapper;

    /**
     * 查询行程人员
     */
    @Override
    public TripMemberVo queryById(Long memberId) {
        return baseMapper.selectVoById(memberId);
    }

    /**
     * 查询行程人员列表
     */
    @Override
    public TableDataInfo<TripMemberVo> queryPageList(TripMemberBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TripMember> lqw = buildQueryWrapper(bo);
        Page<TripMemberVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询行程人员列表
     */
    @Override
    public List<TripMemberVo> queryList(TripMemberBo bo) {
        LambdaQueryWrapper<TripMember> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TripMember> buildQueryWrapper(TripMemberBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TripMember> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getMemberName()), TripMember::getMemberName, bo.getMemberName());
        return lqw;
    }

    /**
     * 新增行程人员
     */
    @Override
    public Boolean insertByBo(TripMemberBo bo) {
        TripMember add = BeanUtil.toBean(bo, TripMember.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setMemberId(add.getMemberId());
        }
        return flag;
    }

    /**
     * 修改行程人员
     */
    @Override
    public Boolean updateByBo(TripMemberBo bo) {
        TripMember update = BeanUtil.toBean(bo, TripMember.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TripMember entity) {
        // 做一些数据校验,如唯一约束,名称不能重复
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<TripMember>().eq(TripMember::getMemberName, entity.getMemberName())
                .ne(ObjectUtil.isNotNull(entity.getMemberId()), TripMember::getMemberId, entity.getMemberId()));
        if (exists) {
            throw new BlogException("trip.member.add.not.unique");
        }
    }

    /**
     * 批量删除行程人员
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 校验是否关联行程
            checkHasTrip(ids);
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 检查有行程
     *
     * @param ids
     * @author ANH
     * @date 2024/12/07
     */
    private void checkHasTrip(Collection<Long> ids) {
        // 检查是否绑定了行程的指派人
        List<TripDailyRecord> assignerHasRecords = tripDailyRecordMapper.selectList(new LambdaQueryWrapper<TripDailyRecord>()
                .in(CollUtil.isNotEmpty(ids), TripDailyRecord::getAssigner, ids));
        if (CollUtil.isNotEmpty(assignerHasRecords)) {
            List<Long> assigners = assignerHasRecords.stream().map(TripDailyRecord::getAssigner).collect(Collectors.toList());
            throw new TripException("trip.member.delete.assigner.has.trip", StringUtils.join(assigners, ","));
        }
        // 检查是否绑定了行程的发车人
        List<TripDailyRecord> driverHasRecords = tripDailyRecordMapper.selectList(new LambdaQueryWrapper<TripDailyRecord>()
                .in(CollUtil.isNotEmpty(ids), TripDailyRecord::getDriver, ids));
        if (CollUtil.isNotEmpty(driverHasRecords)) {
            List<Long> drivers = driverHasRecords.stream().map(TripDailyRecord::getAssigner).collect(Collectors.toList());
            throw new TripException("trip.member.delete.driver.has.trip", StringUtils.join(drivers, ","));
        }
    }

    /**
     * 查询所有成员
     *
     * @return {@link List }<{@link TripMemberVo }>
     * @author ANH
     * @date 2024/12/07
     */
    @Override
    public List<TripMemberVo> queryAllMembers() {
        List<TripMember> tripMembers = baseMapper.selectList();
        return BeanCopyUtils.copyList(tripMembers, TripMemberVo.class);
    }

    /**
     * 导入数据
     *
     * @param volist 声标
     * @author ANH
     * @date 2024/12/06
     */
    @Override
    public void importData(List<TripMemberVo> volist) {
        List<TripMember> tripMembers = baseMapper.selectList();
        Set<String> existingNames = tripMembers.stream().map(TripMember::getMemberName).collect(Collectors.toSet());
        Set<String> uniqueNames = new HashSet<>();
        List<TripMember> memberList = volist.stream()
                .filter(vo -> uniqueNames.add(vo.getMemberName()))
                .filter(vo -> !existingNames.contains(vo.getMemberName()))
                .map(vo -> BeanUtil.toBean(vo, TripMember.class))
                .collect(Collectors.toList());
        baseMapper.insertBatch(memberList);
    }


}
